package dsx.rpcProxy;

import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import dsx.config.Config;
import dsx.config.ConfigItem;
import dsx.console.DsxConsole;
import dsx.inf.IConverter;
import dsx.inf.INetProxy;
import dsx.inf.ISlicer;
import dsx.log.ServLog;
import dsx.system.DsxClassLoader;

public class RPCProxy {

	INetProxy netProxy = null;
	ISlicer slicer = null;
	IConverter converter = null;
	static int status = 0; // 状态：0 关闭，1 启动

	static HashMap<String, RPCProxy> proxyMap = new HashMap<String, RPCProxy>();

	public static void start() {
		synchronized (proxyMap) {
			if (status != 0)
				return;
			ArrayList<_RPCProxy> configs = loadConfig();
			for (_RPCProxy config : configs) {
				try {
					RPCProxy proxy = new RPCProxy();
					URLClassLoader loader = (URLClassLoader) DsxClassLoader
							.frameClassLoader();
					if (config.slicerClass.equals(""))
						proxy.slicer = null;
					else
						proxy.slicer = (ISlicer) loader.loadClass(
								config.slicerClass).newInstance();
					proxy.converter = (IConverter) loader.loadClass(
							config.converterClass).newInstance();
					proxy.netProxy = (INetProxy) loader.loadClass(
							config.netProxyClass).newInstance();
					proxy.netProxy.start(config.netProxyName, proxy.slicer,
							proxy.converter);
					proxyMap.put(config.proxyName, proxy);
				} catch (Exception ex) {
					DsxConsole.out(ex.getMessage(), "rpcProxy", ServLog.error);
				}
			}
			status = 1;
		}
	}

	public static Object request(String proxyName, Object reqObj,
			Class<?> answType) {
		if (status == 0)
			start();
		INetProxy netProxy;
		synchronized (proxyMap) {
			netProxy = proxyMap.get(proxyName).netProxy;
		}
		if (netProxy == null)
			return null;
		return netProxy.request(reqObj, answType);
	}

	public static Object request(String proxyName, Object reqObj,
			Class<?> answType, String host, int port) {
		if (status == 0)
			start();
		INetProxy netProxy;
		synchronized (proxyMap) {
			netProxy = proxyMap.get(proxyName).netProxy;
		}
		if (netProxy == null)
			return null;
		return netProxy.request(reqObj, answType, host, port);
	}

	public static void stop() {
		synchronized (proxyMap) {
			if (status == 0)
				return;
			for (Entry<String, RPCProxy> entry : proxyMap.entrySet()) {
				try {
					entry.getValue().netProxy.stop();
				} catch (Exception ex) {
				}
			}
			proxyMap.clear();
		}
	}

	private static ArrayList<_RPCProxy> loadConfig() {
		ArrayList<_RPCProxy> ret = new ArrayList<_RPCProxy>();
		try {
			ArrayList<ArrayList<ConfigItem>> sections = Config
					.getSections("RPCProxy");
			for (int i = 0; i < sections.size(); i++) {
				ArrayList<ConfigItem> fields = sections.get(i);
				_RPCProxy config = new _RPCProxy();
				for (int j = 0; j < fields.size(); j++) {
					ConfigItem field = fields.get(j);
					switch (field.name) {
					case "proxyName":
						config.setProxyName(field.value);
						break;
					case "converterClass":
						config.setConverterClass(field.value);
						break;
					case "slicerClass":
						config.setSlicerClass(field.value);
						break;
					case "netProxyName":
						config.setNetProxyName(field.value);
						break;
					case "netProxyClass":
						config.setNetProxyClass(field.value);
						break;
					}
				}
				ret.add(config);
			}
		} catch (Exception ex) {
			DsxConsole.out(ex.getMessage(), "rpcProxy", ServLog.error);
		} 
		return ret;
	}

}
